package com.artezio.task.controllers;

import com.artezio.task.dto.FormatDataDto;
import com.artezio.task.dto.SearchDto;
import com.artezio.task.model.Contact;
import com.artezio.task.model.ContactTelDetail;
import com.artezio.task.services.ContactsService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

@Controller
public class ContactsController {

    @Autowired
    private ContactsService contactsService;


    protected final Log logger = LogFactory.getLog(getClass());

    @RequestMapping(value = "/contacts.html")
    public String showForm(Model model) {
//        model.addAttribute("param1", "Hello world!");
        return "contacts";
    }

    //    @RequestMapping(value = "/j_spring_security_check")
//    public String user(Model model) {
////        model.addAttribute("param1", "Hello world!");
//        return "j_spring_security_check";
//    }
    @RequestMapping(value = {"/", "/index.html"}, method = RequestMethod.GET)
    public String start(Model model) {
//        model.addAttribute("param1", "Hello world!");
        return "index";
    }

    @RequestMapping(value = "/error.html", method = RequestMethod.GET)
    public String error(Model model) {
//        model.addAttribute("param1", "Hello world!");
        return "error";
    }

    @RequestMapping(value = "/login.html", method = RequestMethod.GET)
    public String login(ModelMap model) {
        return "login";
    }

    @RequestMapping(value = "/loginfailed", method = RequestMethod.GET)
    public String loginerror(ModelMap model) {
        model.addAttribute("error", "Неверный пароль");
        return "login";
    }

    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(ModelMap model) {
        return "index";
    }

    @RequestMapping(value = "/contacts.html", method = RequestMethod.GET)
    public ModelAndView showData(Model model, SearchDto dto) {

        List<Contact> contacts = contactsService.getAllContacts();
        ModelAndView mvc = new ModelAndView("contacts");
        mvc.addObject("contactList", contacts);
        return mvc;
    }


//    @RequestMapping(value = "/contactsbyname.html", method = RequestMethod.POST)
//    public
//    @ResponseBody
//    String addUser(@ModelAttribute(value = "user") User user, BindingResult result) {
//        String returnText;
//        if (!result.hasErrors()) {
//            userList.add(user);
//            returnText = "User has been added to the list. Total number of users are " + userList.size();
//        } else {
//            returnText = "Sorry, an error has occur. User has not been added to list.";
//        }
//        return returnText;
//    }

    @RequestMapping(value = "/contactsbylastname.html", method = RequestMethod.POST)
    public String showFilterDataSortByLastName(Model model, SearchDto dto) {
        String firstName = dto.getFirstName();
        String lastName = dto.getLastName();
        String telType = dto.getTelType();
        String telNumber = dto.getTelNumber();
        String norder = dto.getNorder();
        String lnorder = dto.getLnorder();
        if (lnorder.isEmpty()) {
            norder = "lndesc";
        }

        List<Contact> contacts = contactsService.getContactsByCriteriaSortByLastNameAjax(firstName, lastName, telType, telNumber, lnorder);
        model.addAttribute("contactList", contacts);
//        model.addAttribute("norder", norder);
//        model.addAttribute("lnorder", lnorder);


        if (lnorder.equals("lnasc")) {
            lnorder = "lndesc";
        } else lnorder = "lnasc";

        //lnorder = lnorder.equals("lnasc") ? "lndesc" : "lnasc";

        dto.setLnorder(lnorder);
        dto.setNorder(norder);

        return "contacts";
    }
//    Контроллеры-фильтры

    @RequestMapping(value = "/contacts.html", method = RequestMethod.POST)
    public String showFilterData(Model model, SearchDto dto) {
        String firstName = dto.getFirstName();
        String lastName = dto.getLastName();
        String telType = dto.getTelType();
        String telNumber = dto.getTelNumber();


        List<Contact> contacts = contactsService.getContactsByCriteria(firstName, lastName, telType, telNumber);
//        List<Contact> contacts = contactsService.getContactsByCriteriaSortByNameAjax(firstName, lastName, telType, telNumber);
//        List<Contact> contacts = contactsService.getContactsByCriteriaSortByLastNameAjax(firstName, lastName, telType, telNumber);
        model.addAttribute("contactList", contacts);
        return "contacts";
    }

    //    Контроллеры-фильтры


    @RequestMapping(value = "/addcontact.html", method = RequestMethod.GET)
    public String addContact(Model model) {
        model.addAttribute(new FormatDataDto());
        return "addcontact";
    }

    @RequestMapping(value = "/addcontact.html", method = RequestMethod.POST)
    public String addContact(@Valid FormatDataDto dto, BindingResult bindingResult, Model model) {
        if (bindingResult.hasErrors()) {
            return "addcontact";
        }
        Contact contact = new Contact();
        contact.setDataFromDto(dto);
        contactsService.addNewContact(contact);

        return "redirect:contacts.html";
    }

    @RequestMapping(value = "/editcontact.html", method = RequestMethod.GET)
    public String editContact(Model model, @RequestParam(value = "id", required = true) Integer idcont) {
//        int idcont = Integer.parseInt(id);
        Contact contact = contactsService.findContactById(idcont);
        FormatDataDto dto = new FormatDataDto();
        dto.initContact(contact);
        model.addAttribute(dto);
        return "editcontact";
    }


    @RequestMapping(value = "/editcontact.html", method = RequestMethod.POST)
    public String editContact(@Valid FormatDataDto dto, BindingResult bindingResult, Model model) {
        if (bindingResult.hasErrors()) {
            return "editcontact";
        }
        Contact contact = contactsService.findContactById(dto.getId());
        contact.setDataFromDto(dto);
        contactsService.saveContact(contact);
        //contactsService.addNewContact(contact);

        return "redirect:contacts.html";
    }

    @RequestMapping(value = "/addnumber.html", method = RequestMethod.GET)
    public String addNumber(Model model, @RequestParam("idContact") String id) {
        int idContact = Integer.parseInt(id);
        Contact contact = contactsService.findContactById(idContact);
        FormatDataDto dto = new FormatDataDto();
        //dto.setId(idContact);
        dto.initContact(contact);
        model.addAttribute(dto);
        return "addnumber";
    }


    @RequestMapping(value = "/addnumber.html", method = RequestMethod.POST)
    public String addNumber(@Valid FormatDataDto dto, BindingResult bindingResult, Model model) {
        if (bindingResult.hasErrors()) {
            return "addnumber";
        }
        int contactId = dto.getId();
        Contact contact = contactsService.findContactById(contactId);
        ContactTelDetail contactTelDetail = new ContactTelDetail();
        contactTelDetail.newInit(dto);
        contactTelDetail.setContact(contact);
        contact.addContactTelDetail(contactTelDetail);
        //contactsService.addNewContactTelDetail(contact, contactTelDetail);
        contactsService.saveContact(contact);

        return "redirect:editcontact.html?id=" + contactId;
    }


    @RequestMapping(value = "/editnumber.html", method = RequestMethod.GET)
    public String editNumber(Model model, @RequestParam("idNumber") String idN, @RequestParam("id") String id) {

        int idNumber = Integer.parseInt(idN);
        ContactTelDetail det = contactsService.findContactTelDetailById(idNumber);
        FormatDataDto dto = new FormatDataDto();
        dto.initByContNumber(det);
        int idC = Integer.parseInt(id);
        dto.setId(idC);
        model.addAttribute(dto);

        return "editnumber";
    }

    @RequestMapping(value = "/editnumber.html", method = RequestMethod.POST)
    public String editNumber(@Valid FormatDataDto dto, BindingResult bindingResult, Model model) {
        if (bindingResult.hasErrors()) {
            return "editnumber.html?id=" + dto.getId();
        }

        ContactTelDetail det = contactsService.findContactTelDetailById(dto.getIdNumber());
        det.initByDto(dto);
        contactsService.saveContactTelDetail(det);


        //contactsService.addNewContact(contact);

        return "redirect:editcontact.html?id=" + dto.getId();
    }

    @RequestMapping(value = "/deletecontact.html", method = RequestMethod.GET)
    public String deleteContact(Model model, @RequestParam("id") String id) {
        int idcont = Integer.parseInt(id);
        Contact contact = contactsService.findContactById(idcont);
        contactsService.deleteContact(contact);
        return "redirect:contacts.html";
    }

    @RequestMapping(value = "/deletnumber.html", method = RequestMethod.GET)
    public String deleteNumber(Model model, @RequestParam("id") String id, @RequestParam("idContact") String idcont) {
        int idDet = Integer.parseInt(id);
        ContactTelDetail contactTelDetail = contactsService.findContactTelDetailById(idDet);
        contactsService.deleteContactTelDetail(contactTelDetail);
        return "redirect:editcontact.html?id=" + idcont;
    }

//    @RequestMapping(value = "/sortbyname.html", method = RequestMethod.GET)
//    public
//    @ResponseBody
//    String sortByName(@ModelAttribute(value = "contact") Contact contact, BindingResult result) {
//        String returnText = "";
////        if (result.hasErrors()) {
////            returnText = "Sorry ERROR";
////        }
//
//        return "{  \"sEcho\": 2," +
//                "   \"iTotalRecords\": 2," +
//                "   \"iTotalDisplayRecords\": 2," +
//                "   \"aaData\": [" +
//                "       [" +
//                "           \"Gecko\"," +
//                "           \"Firefox 1.0\"," +
//                "           \"Win 98+ / OSX.2+\"," +
//                "           \"1.7\"," +
//                "           \"A\"" +
//                "       ]," +
//                "       [" +
//                "           \"Gecko\"," +
//                "           \"Firefox 1.5\"," +
//                "           \"Win 98+ / OSX.2+\"," +
//                "           \"1.8\"," +
//                "           \"A\"" +
//                "       ]" +
//                "   ]" +
//                "}";
//    }


    @RequestMapping(value = "/contactsbyname.html", method = RequestMethod.POST)
    public
//    @ResponseBody
    String showFilterDataSortByName(Model model, SearchDto dto) {
        String firstName = dto.getFirstName();
        String lastName = dto.getLastName();
        String telType = dto.getTelType();
        String telNumber = dto.getTelNumber();
        String norder = dto.getNorder();
        String lnorder = dto.getLnorder();
        if (norder.isEmpty()) {
            norder = "ndesc";
        }

        List<Contact> contacts = contactsService.getContactsByCriteriaSortByNameAjax(firstName, lastName, telType, telNumber, norder);
        model.addAttribute("contactList", contacts);
        if (norder.equals("nasc")) {
            norder = "ndesc";
        } else norder = "nasc";
        dto.setLnorder(lnorder);
        dto.setNorder(norder);
        return "contacts";
//        return model.toString();
    }

    @RequestMapping(value = "/viewcontactajax.html")
    @ResponseBody
    public Map<String, Object> viewNumbersAjax(HttpServletRequest req, Map<String, Object> map, @RequestParam("idContact") String idcont) {
        int idC = Integer.parseInt(idcont);
        Contact contact = contactsService.findContactById(idC);

        Map<String, Object> data = new TreeMap<String, Object>();
        List rows = new ArrayList();
        List<ContactTelDetail> dets = contact.getContactTelDetails();
        for (ContactTelDetail det : dets) {
            List<String> row = new ArrayList<String>();
            row.add(det.getTelType());
            row.add(det.getTelNumber());
            row.add("<a href=\"editnumber.html?idNumber=" + det.getId() + "&id=" + det.getContact().getId() + "\">править</a>");
//            row.add("<input type=\"button\" onclick=\"deleteNumber('" + det.getId() + "," + det.getContact().getId() + "');\" id=\"" + det.getId() + "\" value=\"удалить\"/>");
            row.add("<input type=\"button\" onclick=\"return deleteNumber(" + det.getId() + "," + det.getContact().getId() + ")\" value=\"удалить\"/>");


            rows.add(row);
        }
        data.put("sEcho", 3000);
        data.put("iTotalRecords", dets.size());
        data.put("iTotalDisplayRecords", dets.size());
        data.put("aaData", rows);
        return data;
    }

    @RequestMapping(value = "/deletenumberajax.html")
    @ResponseBody
    public Map<String, Object> deleteNumberAjax(HttpServletRequest req, Map<String, Object> map, @RequestParam("idDet") String id, @RequestParam("idContact") String idc) {
        int idC = Integer.parseInt(idc);
        int idDet = Integer.parseInt(id);
        ContactTelDetail contactTelDetail = contactsService.findContactTelDetailById(idDet);
        contactsService.deleteContactTelDetail(contactTelDetail);
        Contact contact = contactsService.findContactById(idC);

        Map<String, Object> data = new TreeMap<String, Object>();
        List rows = new ArrayList();
        List<ContactTelDetail> dets = contact.getContactTelDetails();
        for (ContactTelDetail det : dets) {
            List<String> row = new ArrayList<String>();
            row.add(det.getTelType());
            row.add(det.getTelNumber());
            row.add("<a href=\"editnumber.html?idNumber=" + det.getId() + "&id=" + det.getContact().getId() + "\">править</a>");
            row.add("<input type=\"button\" onclick=\"return deleteNumber(" + det.getId() + "," + det.getContact().getId() + ")\" value=\"удалить\"/>");
            rows.add(row);
        }
        data.put("sEcho", 3000);
        data.put("iTotalRecords", dets.size());
        data.put("iTotalDisplayRecords", dets.size());
        data.put("aaData", rows);
        return data;
    }

    @RequestMapping(value = "/contactsajax.html")
    @ResponseBody
    public Map<String, Object> getContactsAjax(@RequestParam("iDisplayStart") int displayStart_r, @RequestParam("iDisplayLength") int displayLength_r, @RequestParam("sSearch") String sSearch_r, @RequestParam("sSortDir_0") String sSortDir_0_r, @RequestParam("iSortCol_0") int iSortCol_0_r) throws UnsupportedEncodingException {
//        double echo = Math.random()*100%1;
//        int e = Integer.parseInt(String.valueOf(echo));
        String firstName = "";
        String lastName = "";
        int firstRes = displayStart_r;
        int maxRes = displayLength_r;
        int iSortCol_0 = iSortCol_0_r; //     2 - firstName 3 - lastName
        String sSortDir_0 = sSortDir_0_r; //   asc desc
        String order = "";
        String str = URLEncoder.encode(sSearch_r, "UTF-8");
        String sSearch_ISO = URLDecoder.decode(str, "UTF-8");
        String sSearch = new String(sSearch_ISO.getBytes("ISO-8859-1"), "UTF-8");
        if (iSortCol_0 == 1) {
            order = "fn" + sSortDir_0;
        } else if (iSortCol_0 == 2) {
            order = "ln" + sSortDir_0;
        } else order = "fnasc";

        List<Contact> contacts = contactsService.getContactsByCriteriaPaginAjax(firstName, lastName, maxRes, firstRes, order, sSearch);

        Collection<GrantedAuthority> auts = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
        boolean root = false;
        boolean user = false;
        for (GrantedAuthority g : auts) {
            if (g.toString().equals("ROLE_ADMIN")) {
                root = true;
            }
            if (g.toString().equals("ROLE_USER")) {
                user = true;
            }
        }

        Map<String, Object> data = new TreeMap<String, Object>();
        List rows = new ArrayList();
        int n = 1;
        for (Contact cont : contacts) {
            List<String> row = new ArrayList<String>();
            row.add(String.valueOf(n++));

//            else row.add("*");
//            row.add("<input type=\"button\" onclick=\"return deleteContact(" + cont.getId() + ")\" value=\"удалить\"/>");
            row.add(cont.getFirstName());
            row.add(cont.getLastName());
            row.add(cont.allDets());
            if (root) {
                row.add("<a href=\"editcontact.html?id=" + cont.getId() + "\">править</a>");
            }
            if (root) {
                String confirm = "' onClick = \" return window.confirm('Вы действительно хотите удалить контакт " + cont.getFirstName() + " " + cont.getLastName() + " ?')\"";
                row.add("<a href='deletecontact.html?id=" + cont.getId() + confirm + "'>удалить</a>");
            }
//            else row.add("*");
            rows.add(row);
        }

//        data.put("sEcho", e);
//        data.put("aoColumnDefs","[{ \"bVisible\": false, \"aTargets\": [0] }]");
        data.put("iTotalRecords", contacts.size());
        data.put("iTotalDisplayRecords", contacts.size());
        data.put("aaData", rows);

//        data.put("root",true);

        return data;
    }

//    @RequestMapping(value = "/deletecontactajax.html")
//    @ResponseBody
//    public Map<String, Object> deleteContactsAjax(@RequestParam("iDisplayStart") int displayStart_r, @RequestParam("iDisplayLength") int displayLength_r, @RequestParam("sSearch") String sSearch_r, @RequestParam("sSortDir_0") String sSortDir_0_r, @RequestParam("iSortCol_0") int iSortCol_0_r, @RequestParam("id") int id) throws UnsupportedEncodingException {
//        String firstName = "";
//        String lastName = "";
//        int firstRes = displayStart_r;
//        int maxRes = displayLength_r;
//        int iSortCol_0 = iSortCol_0_r; //     2 - firstName 3 - lastName
//        String sSortDir_0 = sSortDir_0_r; //   asc desc
//        String order = "";
//        String sSearch = sSearch_r;
//
//        if (iSortCol_0 == 2) {
//            order = "fn" + sSortDir_0;
//        } else if (iSortCol_0 == 3) {
//            order = "ln" + sSortDir_0;
//        }
//        if (id != 0) {
//
//            contactsService.deleteContactById(id);
//        }
//        List<Contact> contacts = contactsService.getContactsByCriteriaPaginAjax(firstName, lastName, maxRes, firstRes, order, sSearch);
//
//
//        Map<String, Object> data = new TreeMap<String, Object>();
//        List rows = new ArrayList();
//
//        for (Contact cont : contacts) {
//            List<String> row = new ArrayList<String>();
//            row.add("<a href=\"editcontact.html?id=" + cont.getId() + "\">править</a>");
//            row.add("<input type=\"button\" onclick=\"return deleteContact(" + cont.getId() + ")\" value=\"удалить\"/>");
//            row.add(cont.getFirstName());
//            row.add(cont.getLastName());
//            row.add(cont.allDets());
//            rows.add(row);
//        }
////        data.put("sEcho", 3000);
//        data.put("iTotalRecords", contacts.size());
//        data.put("iTotalDisplayRecords", contacts.size());
//        data.put("aaData", rows);
//        return data;
//    }


}